package com.spzx.cart.listener;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.rabbitmq.client.Channel;
import com.spzx.cart.service.CartService;
import com.spzx.common.core.utils.StringUtils;
import com.spzx.common.rabbitmq.constants.SpzxRabbitmqConstants;
import jakarta.annotation.Resource;
import org.springframework.amqp.core.ExchangeTypes;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.concurrent.TimeUnit;

@Component
public class SpzxCartMqListener {
    @Resource
    CartService cartService;
    @Resource
    StringRedisTemplate stringRedisTemplate;
    @RabbitListener(queues = {SpzxRabbitmqConstants.ORDER_SUBMIT_CART_QUEUE})
    public void orderSubmitListener(String message , Message msg , Channel channel){

        try {
            //消费者业务: 删除购物车中选中的购物项
            //消息可能重复发送，需要保证幂等性
            Boolean flag = stringRedisTemplate.opsForValue().setIfAbsent("spzx:cart:lock:" + message, "1", 5,
                    TimeUnit.MINUTES);
            if(flag){
                JSONObject jsonObject = JSON.parseObject(message, JSONObject.class);
                if(!StringUtils.isEmpty(jsonObject.getString("source") )
                        && jsonObject.getString("source").equals("1")){
                    cartService.delCheckedCartItems(jsonObject.getLong("userId"));

                }
            }
            //手动ack
            channel.basicAck(msg.getMessageProperties().getDeliveryTag(),
                    false);
        } catch (Exception e) {
//            throw new RuntimeException(e);
            try {
                if(msg.getMessageProperties().isRedelivered()){
                    //是消费异常重新归队后 再次消费进入异常  丢弃消息：变为死信
                    channel.basicReject(msg.getMessageProperties().getDeliveryTag(),false);
                }else{
                    //第一次消费异常 让消息归队 尝试重新消费
                    channel.basicNack(msg.getMessageProperties().getDeliveryTag(),false,true);
                }
            } catch (IOException ex) {
                throw new RuntimeException(ex);
            }
        }

    }
}
